import React, { useState , useEffect, useCallback} from 'react'
import { BaseTable, BaseTableProps} from './components/Table'
import { sort } from './components/Sort'
import {SortItem} from './type/interfaces'
import {  arraySort, smartCompare } from './utils-func'
import { transform } from './helpers/transform'
import Pagination, {PaginationProps} from './components/Pagination'

const defaultPaginationProps: PaginationProps =  {
    totalItems: 0,
    itemsPerPage: 10,
    onPageChange: () => {},
    initPageNum: 1,
}


function SortableTable(props: BaseTableProps & {pagination: PaginationProps}) {

    const {dataSource, columns, pagination } = props

    const [sorts, onChangeSorts] = useState<Array<SortItem>>([])
    const [wrapperColumns, setWrapperColumns] = useState(columns)
    const [sortedDataSource, setSortedDataSource] = useState(dataSource)
    const [currentList, setCurrentList] = useState<any []>([])
    const [sortColumnsMap] = useState(new Map(
        wrapperColumns
          .filter((col) => col?.sortable !== false && col?.sortable != null)
          .map((col) => [col.code, col]),
      ))

    const [wrapperPagination] = useState({...defaultPaginationProps, ...pagination, totalItems: dataSource?.length})
    const [currentPageNum, setCurrentPageNum] = useState<number>(pagination.initPageNum || defaultPaginationProps.initPageNum)

    const onPageChange = useCallback((pageNum: number) => {
        let startIndex = (pageNum-1) * wrapperPagination.itemsPerPage
        setCurrentPageNum(pageNum)
        pagination?.onPageChange && pagination?.onPageChange(pageNum)
        setCurrentList(sortedDataSource.slice(startIndex,startIndex +  wrapperPagination.itemsPerPage))
    }, [sortedDataSource])

    const handleSort = useCallback((nextSort: Array<SortItem>) => {
       let data =  arraySort(dataSource, (x, y) => {
            for (const { code, order } of nextSort) {
              const column = sortColumnsMap.get(code)
              // 如果 code 对应的 column 不可排序，跳过该 code
              if (column == null) {
                continue
              }
              const sortable = column.sortable
              const compareFn = typeof sortable === 'function' ? sortable : smartCompare
              const xValue = transform.safeGetValue(column, x, -1)
              const yValue = transform.safeGetValue(column, y, -1)
              const cmp = compareFn(xValue, yValue, x, y)
              if (cmp !== 0) {
                return cmp * (order === 'asc' ? 1 : -1)
              }
            }
            return 0
          })
          setSortedDataSource(data)
          onChangeSorts(nextSort)

    }, [sorts])

    useEffect(() => {
        let temp = sort({sorts, onChangeSorts: handleSort})(columns)
        setWrapperColumns(temp)
        let startIndex = (currentPageNum-1) * wrapperPagination.itemsPerPage
        setCurrentList(sortedDataSource.slice(startIndex, startIndex + wrapperPagination.itemsPerPage))

    }, [sorts])

    return <>
     <BaseTable {...props} dataSource={currentList} columns={wrapperColumns} />
     <Pagination {...wrapperPagination} onPageChange={onPageChange} />
    </>

  }


export { BaseTable, BaseTableProps } 
export { SortableTable } 